const mongoose = require('mongoose');

// MongoDB 连接配置
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/shoreDB';

// 连接选项
const CONNECTION_OPTIONS = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  serverSelectionTimeoutMS: 5000, // 5秒服务器选择超时
  socketTimeoutMS: 45000, // 45秒socket超时
  family: 4, // 使用 IPv4, 跳过 IPv6
};

// 连接状态
let isConnected = false;
let connectionRetries = 0;
const MAX_RETRIES = 5;

// 连接到 MongoDB
async function connectToDatabase() {
  if (isConnected) {
    console.log('使用现有的数据库连接');
    return mongoose.connection;
  }

  try {
    console.log(`尝试连接到 MongoDB: ${MONGODB_URI}`);
    
    // 设置事件监听器
    mongoose.connection.on('connected', () => {
      console.log('Mongoose 已连接到 MongoDB');
      isConnected = true;
      connectionRetries = 0;
    });

    mongoose.connection.on('error', (err) => {
      console.error('Mongoose 连接错误:', err);
      isConnected = false;
    });

    mongoose.connection.on('disconnected', () => {
      console.log('Mongoose 已断开与 MongoDB 的连接');
      isConnected = false;
    });

    // 连接到数据库
    await mongoose.connect(MONGODB_URI, CONNECTION_OPTIONS);
    
    console.log('成功连接到 MongoDB');
    isConnected = true;
    
    return mongoose.connection;
  } catch (error) {
    connectionRetries++;
    console.error(`连接到 MongoDB 失败 (尝试 ${connectionRetries}/${MAX_RETRIES}):`, error.message);
    
    if (connectionRetries >= MAX_RETRIES) {
      console.error('已达到最大重试次数，放弃连接');
      throw new Error(`无法连接到 MongoDB: ${error.message}`);
    }
    
    // 等待一段时间后重试
    await new Promise(resolve => setTimeout(resolve, 2000));
    return connectToDatabase();
  }
}

// 关闭数据库连接
async function closeDatabaseConnection() {
  if (isConnected) {
    try {
      await mongoose.connection.close();
      console.log('MongoDB 连接已关闭');
      isConnected = false;
    } catch (error) {
      console.error('关闭 MongoDB 连接时出错:', error);
    }
  }
}

// 测试连接
async function testConnection() {
  try {
    const connection = await connectToDatabase();
    // 执行一个简单的查询来测试连接
    await connection.db.admin().ping();
    return { success: true, message: 'MongoDB 连接正常' };
  } catch (error) {
    return { success: false, message: error.message };
  }
}

// 当应用程序退出时关闭连接
process.on('SIGINT', async () => {
  await closeDatabaseConnection();
  process.exit(0);
});

module.exports = {
  connectToDatabase,
  closeDatabaseConnection,
  testConnection,
  mongoose // 导出 mongoose 实例以便在其他地方使用
};